package com.zjcode.cdcer.job;

import com.alibaba.fastjson.JSONObject;
import com.chinatechstar.component.commons.utils.StringUtils;
import com.chinatechstar.component.commons.utils.UuidUtil;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.zjcode.cdcer.config.MConsts;
import com.zjcode.cdcer.config.MConsts.JOB_EXECUTE_TYPE;
import com.zjcode.cdcer.mapper.*;
import com.zjcode.cdcer.model.*;
import com.zjcode.cdcer.pojo.CerSysteminitImportInfo;
import com.zjcode.cdcer.service.CerDataScreenService;
import com.zjcode.cdcer.service.CerDetaildataImportInfoService;
import com.zjcode.cdcer.service.TkmJobLogsService;
import com.zjcode.cdcer.service.TkmSysteminitImportInfoService;
import com.zjcode.cdcer.utils.RedisUtils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
import java.util.Map.Entry;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StopWatch;

import java.text.NumberFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName:TkmJobHandler
 * @功能：任务处理器
 * @author：wlei
 * @日期：2022/8/16-03:05
 **/
@Component
@Slf4j
public class TkmJobHandler {

    @Autowired
    private TkmSysteminitImportInfoService tkmSysteminitImportInfoService;
    @Autowired
    private CerDetaildataImportInfoService cerDetaildataImportInfoService;
    @Autowired
    private TkmJobLogsService tkmJobLogsService;
    @Autowired
    private CerReportProgress2Mapper cerReportProgressMapper;
    //初始数据上报正式库
    @Autowired
    private CerSysteminitImportOfficialInfoMapper cerSysteminitImportOfficialInfoMapper;
    //详情数据正式库
    @Autowired
    private CerDetaildataImportOfficeInfoMapper cerDetaildataImportOfficeInfoMapper;
    @Autowired
    private CerSysteminitImportInfoMapper cerSysteminitImportInfoMapper;
    //详情数据上报
    @Autowired
    private CerDetaildataImportInfoMapper cerDetaildataImportInfoMapper;

    @Autowired
    private ZjcodeSysRegionMapper zjcodeSysRegionMapper;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private CerDataScreenService cerDataScreenService;

    /**
     * 获取任务日志实体
     *
     * @param now
     * @param content
     * @param operateType
     * @return
     */
    private static TkmJobLogs getJobLogs(LocalDate now, String content, int operateType) {
        TkmJobLogs tkmJobLogs = new TkmJobLogs();
        tkmJobLogs.setId(UuidUtil.get32UUID());
        tkmJobLogs.setExecuteDate(new Date(System.currentTimeMillis()));
        tkmJobLogs.setOperateType(operateType);
        tkmJobLogs.setOperateContent(content);
        tkmJobLogs.setExecuteYear(now.getYear() + "");
        tkmJobLogs.setExecuteMonth(now.getMonthValue() + "");
        return tkmJobLogs;
    }

    @XxlJob("healthCheck")
    public void healthCheck(String param) {

        log.info("定时任务健康检测,", LocalDateTime.now());

        XxlJobHelper.log("定时任务健康检测,", LocalDateTime.now());

        XxlJobHelper.handleSuccess("操作成功," + LocalDateTime.now());
    }

    /**
     * 更新上报进度表中的数据
     */
    @XxlJob("updateReportProgressData")
    public void updateReportProgressData() {
        log.info("定时任务:更新上报进度表中的数据");
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        // 1.先清空表数据
        cerReportProgressMapper.deleteAll();
        // 2.调用方法，取出表里最新数据
        // 新建数据集合
        List<CerReportProgress2> list = new ArrayList<>();

        // 初始数据集合
        list.addAll(handleCerReportProgress4Systeminit());
        // 详情数据集合
        list.addAll(handleCerReportProgress4Detail());
        // 返回处理的数据
        List<CerReportProgress2> progresses = handleReginData(list);
        // 执行数据插入
        int batchInsert = cerReportProgressMapper.insertList(progresses);
        stopWatch.stop();
        log.info("耗时:{}", stopWatch.getTotalTimeSeconds());
        XxlJobHelper.handleSuccess("操作成功," + LocalDateTime.now());
    }

    /**
     * 更新详情数据上报的状态
     *
     * @param param
     */
    @XxlJob("updateCerDetailReportmportInfoStatus")
    public void updateCerDetailReportmportInfoStatus(String param) {
        LocalDate now = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String format = now.format(formatter);

        // 获取月初
        LocalDate monthOfFirstDate = LocalDate
            .parse(format, DateTimeFormatter.ofPattern("yyyy-MM-dd"))
            .minusMonths(1)
            .with(TemporalAdjusters.firstDayOfMonth());

        // 获取月末
        LocalDate monthOfLastDate = LocalDate
            .parse(format, DateTimeFormatter.ofPattern("yyyy-MM-dd"))
            .minusMonths(1)
            .with(TemporalAdjusters.lastDayOfMonth());

        String start = monthOfFirstDate.format(formatter);
        String end = monthOfLastDate.format(formatter);

        // 按照日期范围获取出所有没有被上报的初始数据
        List<CerDetaildataImportInfo> list = cerDetaildataImportInfoService.findAllByDateTimeRange(
            start,
            end);

        log.info("按照日期范围获取出所有没有被上报的初始数据,list={}", list.size());

        // 遍历数据,标记数据的上报状态为已超时
        list
            .parallelStream()
            .forEach(each -> {
                // 已超时
                each.setIsUplpadTimeout(1);
                // 标记出错
                each.setIsHaveError(1);
                // 标记错误内容
                String errorMessage = each.getErrorMessage();
                if (StringUtils.isEmpty(errorMessage)) {
                    errorMessage = "超时上报";
                } else {
                    errorMessage += "|超时上报";
                }
                each.setErrorMessage(errorMessage);
                // 设置更新时间
                each.setLastUpdateDatetime(new Date(System.currentTimeMillis()));
            });

        // 更新数据
        list.forEach(each -> cerDetaildataImportInfoService.updateRecord(each));

        // 将操作纪录进日志
        String content = list
            .stream()
            .map(each -> each.getId())
            .collect(Collectors.joining(MConsts.Common.DELIMITER_CHARACTER));
        TkmJobLogs tkmJobLogs = getJobLogs(now, content, JOB_EXECUTE_TYPE.UPDATE_DETAIL_REPORT);
        tkmJobLogsService.insert(tkmJobLogs);

        XxlJobHelper.log("定时任务更新初始数据上报的状态,", LocalDateTime.now());
        XxlJobHelper.handleSuccess("操作成功," + LocalDateTime.now());
    }

    /**
     * 更新初始数据上报的状态
     *
     * @param param
     */
    @XxlJob("updateCerSysteminitImportInfoStatus")
    public void updateCerSysteminitImportInfoStatus(String param) {

        LocalDate now = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String format = now.format(formatter);

        // 获取月初
        LocalDate monthOfFirstDate = LocalDate
            .parse(format, DateTimeFormatter.ofPattern("yyyy-MM-dd"))
            .minusMonths(1)
            .with(TemporalAdjusters.firstDayOfMonth());

        // 获取月末
        LocalDate monthOfLastDate = LocalDate
            .parse(format, DateTimeFormatter.ofPattern("yyyy-MM-dd"))
            .minusMonths(1)
            .with(TemporalAdjusters.lastDayOfMonth());

        String start = monthOfFirstDate.format(formatter);
        String end = monthOfLastDate.format(formatter);

        // 按照日期范围获取出所有没有被上报的初始数据
        List<TkmSysteminitImportInfo> list = tkmSysteminitImportInfoService.findAllByDateTimeRange(
            start,
            end);

        // 遍历数据,标记数据的上报状态为已超时
        list
            .parallelStream()
            .forEach(each -> {
                // 已超时
                each.setIsUplpadTimeout(1);
                // 标记出错
                each.setIsHaveError(1);
                // 标记错误内容
                String errorMessage = each.getErrorMessage();
                if (StringUtils.isEmpty(errorMessage)) {
                    errorMessage = "超时上报";
                } else {
                    errorMessage += "|超时上报";
                }
                each.setErrorMessage(errorMessage);
                // 设置更新时间
                each.setLastUpdateDatetime(new Date(System.currentTimeMillis()));
            });

        // 批量更新数据
        list.forEach(each -> tkmSysteminitImportInfoService.updateRecord(each));

        // 将操作纪录进日志
        String content = list
            .stream()
            .map(each -> each.getId())
            .collect(Collectors.joining(MConsts.Common.DELIMITER_CHARACTER));
        TkmJobLogs tkmJobLogs = getJobLogs(now, content, JOB_EXECUTE_TYPE.UPDATE_INITDATA_REPORT);
        tkmJobLogsService.insert(tkmJobLogs);

        XxlJobHelper.log("定时任务更新初始数据上报的状态,", LocalDateTime.now());
        XxlJobHelper.handleSuccess("操作成功," + LocalDateTime.now());
    }

    /**
     * 更新数据大屏中的数据
     */
    @XxlJob("updateCerDataScreenData")
    public void updateCerDataScreenData() {
        LocalDate now = LocalDate.now();
        int year = now.getYear();
        int monthValue = now.getMonthValue();
        // 指定一个需要具体初始化的月份
        //int monthValue = 10;

        // 更新大屏数据
        cerDataScreenService.updateDataScreenDB(year, monthValue);

        XxlJobHelper.log("定时任务,更新更新数据大屏中的数据,", LocalDateTime.now());
        XxlJobHelper.handleSuccess("操作成功," + LocalDateTime.now());
    }

    /**
     * 初始数据
     *
     * @params detaildataImportOfficeInfos 详情数据正式库数据表
     * @params officeList 初始上报正式库
     */
    private List<CerReportProgress2> handleCerReportProgress4Systeminit() {
        List<CerReportProgress2> list = new ArrayList<>();

        // 获取初始数据正式库中的数据
        // 初始数据正式库-初始上报正式库
        List<CerSysteminitImportOfficialInfo> list4Office = cerSysteminitImportOfficialInfoMapper.queryAllData();
        // list4Office按照创建年份分组
        Map<String, List<CerSysteminitImportOfficialInfo>> map4Office = list4Office
            .stream()
            .collect(Collectors.groupingBy(each -> {
                Date date = each.getInsertDatetime();
                LocalDate localDate = date
                    .toInstant()
                    .atZone(ZoneId.systemDefault())
                    .toLocalDate();
                return String.valueOf(localDate.getYear());
            }));

        // 获取初始数据临时库中的数据
        List<CerSysteminitImportInfo> list4Tmp = cerSysteminitImportInfoMapper.queryAllData();

        // 重置list中的reginCode字段
        list4Tmp = resetRegionCode(list4Tmp);

        if (!CollectionUtils.isEmpty(list4Tmp)) {

            // list4Tmp按照创建年份分组
            Map<String, List<CerSysteminitImportInfo>> map4Tmp = list4Tmp
                .stream()
                .collect(Collectors.groupingBy(each -> {
                    Date date = each.getInsertDatetime();
                    LocalDate localDate = date
                        .toInstant()
                        .atZone(ZoneId.systemDefault())
                        .toLocalDate();
                    return String.valueOf(localDate.getYear());
                }));

            map4Tmp
                .entrySet()
                .forEach(entry -> {
                    String year = entry.getKey();
                    // year下的临时库中的数据
                    List<CerSysteminitImportInfo> listTmp4Year = entry.getValue();

                    //通过reginCode分组数据
                    Map<String, List<CerSysteminitImportInfo>> map = listTmp4Year
                        .parallelStream()
                        .collect(Collectors.groupingBy(CerSysteminitImportInfo::getRegionCode));

                    List<CerReportProgress2> progressList = map
                        .entrySet()
                        .stream()
                        .map(each -> {
                            CerReportProgress2 result = getCerReportProgress4SystemInit(map4Office,
                                                                                        year,
                                                                                        each);

                            return result;
                        })
                        .collect(Collectors.toList());

                    // 重置progressList中的年份字段
                    progressList
                        .parallelStream()
                        .forEach(each -> each.setNf(year));

                    list.addAll(progressList);
                });
        }
        return list;
    }

    private CerReportProgress2 getCerReportProgress4SystemInit(Map<String, List<CerSysteminitImportOfficialInfo>> map4Office,
                                                               String year,
                                                               Entry<String, List<CerSysteminitImportInfo>> each) {
        CerReportProgress2 result = new CerReportProgress2();

        // key:区域编码
        String key = each.getKey();

        // all:当前区域下的所有数据
        List<CerSysteminitImportInfo> all = each.getValue();

        // 按照是否有错误进行分组
        Map<Integer, List<CerSysteminitImportInfo>> groupByErrorType = all
            .parallelStream()
            .collect(Collectors.groupingBy(CerSysteminitImportInfo::getIsHaveError));

        // 有错误的数据
        List<CerSysteminitImportInfo> list4error = getListByErrorCode4Init(groupByErrorType, 1);
        // 无错误的数据
        List<CerSysteminitImportInfo> list4noError = getListByErrorCode4Init(groupByErrorType, 0);
        // 有错误的数据的个数
        int errorCount = list4error.size();
        // 无错误的数据的个数
        int noErrorCount = list4noError.size();
        // 机构名称
        String institutionName = "";
        // 机构id
        String institutionId = "";
        // 省
        String provinceName = "";
        // 市
        String cityName = "";
        // 区县
        String districtName = "";
        if (!CollectionUtils.isEmpty(all)) {
            CerSysteminitImportInfo info = all.get(0);
            // 机构名称
            institutionName = info.getInstitutionName();
            institutionId = info.getInstitutionId();
            provinceName = info.getProvinceName();
            cityName = info.getCityName();
            districtName = info.getDistrictName();
        }

        // 当前年份下初始数据正式库中的数据
        List<CerSysteminitImportOfficialInfo> officeListByYear = map4Office.get(year);
        if (officeListByYear == null) {
            officeListByYear = new ArrayList<>();
        }
        // 从officeListByYear中,按照institutionName,查询出对应机构下的数据
        String finalInstitutionName = institutionName;
        List<CerSysteminitImportOfficialInfo> officeListByInstitutionName = officeListByYear
            .parallelStream()
            .filter(each1 -> each1
                .getInstitutionName()
                .equals(finalInstitutionName))
            .collect(Collectors.toList());
        // 初始数据正式库中符合条件的数据的个数
        int officeCount = officeListByInstitutionName.size();

        // 主键
        result.setId(UuidUtil.get32UUID());
        // 地区组合编码
        String[] split = key.split("\\|");
        // 省份
        result.setProvinceCode(split[0]);
        result.setProvinceName(provinceName);
        // 城市
        result.setCityCode(split[1]);
        result.setCityName(cityName);
        // 区县
        result.setRegionCode(split[2]);
        result.setRegionName(districtName);
        // 上报机构
        result.setInstitutionName(institutionName);
        result.setInstitutionId(institutionId);
        // 总量(胃镜总量)
        String startDate = year + "-01-01";
        String endDate = year + "-12-31";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        int total = 0;
        try {
            total = cerSysteminitImportInfoMapper.countByInsertDatetimeBetweenEqual(sdf.parse(
                startDate), sdf.parse(endDate));
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        result.setTotal(String.valueOf(total));
        // 临时库-应报数 (有错误的数据个数+无错误的数据个数)
        int lskYbs = errorCount + noErrorCount;
        result.setLskYbs(String.valueOf(lskYbs));
        // 临时库-上报进度 (应报数/应报数+初始数据正式库中的数据个数)
        String lskSbjd = getRate(lskYbs, lskYbs + officeCount);
        result.setLskSbjd(lskSbjd);
        // 临时库-合格
        result.setLskHg(String.valueOf(noErrorCount));
        // 临时库-不合格
        result.setLskBhg(String.valueOf(errorCount));
        // 临时库-合格率(合格/合格+不合格)
        String lskHgl = getRate(noErrorCount, noErrorCount + errorCount);
        result.setLskHgl(lskHgl);
        // 正式库-上报数
        result.setZskSbs(String.valueOf(officeCount));
        // 正式库-上报进度(正式库-上报数/应报数+正式库-上报数)
        String zskSbjd = getRate(officeCount, lskYbs + officeCount);
        result.setZskSbjd(zskSbjd);
        // 合计-应报数 (临时库-应报数+正式库-上报数)
        int hjYbs = lskYbs + officeCount;
        result.setHjYbs(String.valueOf(hjYbs));
        // 合计-上报进度(正式库-上报数/合计-应报数)
        result.setHjSbjd(getRate(officeCount, hjYbs));
        // 合计-合格
        result.setHjHg(String.valueOf(officeCount));
        // 合计-不合格
        result.setHjBhg(String.valueOf(errorCount));
        // 合计-合格率 (合格/合格+不合格)
        result.setHjHgl(getRate(officeCount, officeCount + errorCount));
        //初始数据类型
        result.setType(1);
        //deleted
        result.setDeleted(0);
        //插入时间
        result.setInsertDatetime(new Date(System.currentTimeMillis()));
        //更新时间
        result.setLastUpdateDatetime(new Date(System.currentTimeMillis()));
        //ext_flag => 地域数据
        result.setExtFlag(key);
        return result;
    }

    /**
     * 详情数据
     *
     * @params systeminitImportOfficialInfos 初始上报正式库
     * @params detaildataImportOfficeInfos 详情数据正式库数据表
     */
    private List<CerReportProgress2> handleCerReportProgress4Detail() {
        List<CerReportProgress2> list = new ArrayList<>();

        // 初始数据正式库-初始上报正式库
        List<CerSysteminitImportOfficialInfo> init4InitOffice = cerSysteminitImportOfficialInfoMapper.queryAllData();
        // 将初始数据正式库中的数据,按照创建年份分组
        Map<String, List<CerSysteminitImportOfficialInfo>> map4InitOffice = init4InitOffice
            .stream()
            .collect(Collectors.groupingBy(each -> {
                Date date = each.getInsertDatetime();
                LocalDate localDate = date
                    .toInstant()
                    .atZone(ZoneId.systemDefault())
                    .toLocalDate();
                return String.valueOf(localDate.getYear());
            }));

        // 详情数据正式库中的数据
        List<CerDetaildataImportOfficeInfo> list4Office = cerDetaildataImportOfficeInfoMapper.queryAllData();
        // list4Office按照创建年份分组
        Map<String, List<CerDetaildataImportOfficeInfo>> map4Office = list4Office
            .stream()
            .collect(Collectors.groupingBy(each -> {
                Date date = each.getInsertDatetime();
                LocalDate localDate = date
                    .toInstant()
                    .atZone(ZoneId.systemDefault())
                    .toLocalDate();
                return String.valueOf(localDate.getYear());
            }));

        // 详情数据临时库中的数据
        List<CerDetaildataImportInfo> list4Tmp = cerDetaildataImportInfoMapper.queryAllData();

        // 重置list4Tmp中的区域数据
        list4Tmp = handleData4Datail(list4Tmp);

        if (!CollectionUtils.isEmpty(list4Tmp)) {

            // list4Tmp按照创建年份分组
            Map<String, List<CerDetaildataImportInfo>> map4Tmp = list4Tmp
                .stream()
                .collect(Collectors.groupingBy(each -> {
                    Date date = each.getInsertDatetime();
                    LocalDate localDate = date
                        .toInstant()
                        .atZone(ZoneId.systemDefault())
                        .toLocalDate();
                    return String.valueOf(localDate.getYear());
                }));

            map4Tmp
                .entrySet()
                .forEach(entry -> {
                    String year = entry.getKey();
                    // year下的临时库中的数据
                    List<CerDetaildataImportInfo> listTmp4Year = entry.getValue();

                    //通过reginCode分组数据
                    Map<String, List<CerDetaildataImportInfo>> map = listTmp4Year
                        .parallelStream()
                        .collect(Collectors.groupingBy(CerDetaildataImportInfo::getRegionCode));

                    List<CerReportProgress2> progressList = map
                        .entrySet()
                        .stream()
                        .map(each -> {
                            CerReportProgress2 result = getCerReportProgress4Detail(map4InitOffice,
                                                                                    map4Office,
                                                                                    year,
                                                                                    each);

                            return result;
                        })
                        .collect(Collectors.toList());

                    // 重置progressList中的年份字段
                    progressList
                        .parallelStream()
                        .forEach(each -> each.setNf(year));

                    list.addAll(progressList);
                });
        }
        return list;
    }

    private CerReportProgress2 getCerReportProgress4Detail(Map<String, List<CerSysteminitImportOfficialInfo>> map4InitOffice,
                                                           Map<String, List<CerDetaildataImportOfficeInfo>> map4Office,
                                                           String year,
                                                           Entry<String, List<CerDetaildataImportInfo>> each) {
        CerReportProgress2 result = new CerReportProgress2();

        // key:区域编码
        String key = each.getKey();

        // all:当前区域下的所有数据
        List<CerDetaildataImportInfo> all = each.getValue();

        // 按照是否有错误进行分组
        Map<Integer, List<CerDetaildataImportInfo>> groupByErrorType = all
            .parallelStream()
            .collect(Collectors.groupingBy(CerDetaildataImportInfo::getIsHaveError));

        // 有错误的数据
        List<CerDetaildataImportInfo> list4error = getListByErrorCode4Detail(groupByErrorType, 1);
        // 无错误的数据
        List<CerDetaildataImportInfo> list4noError = getListByErrorCode4Detail(groupByErrorType, 0);
        // 有错误的数据的个数
        int errorCount = list4error.size();
        // 无错误的数据的个数
        int noErrorCount = list4noError.size();
        // 机构名称
        String institutionName = "";
        // 机构id
        String institutionId = "";
        // 省
        String provinceName = "";
        // 市
        String cityName = "";
        // 区县
        String districtName = "";
        if (!CollectionUtils.isEmpty(all)) {
            CerDetaildataImportInfo info = all.get(0);
            // 机构名称
            institutionName = info.getInstitutionName();
            institutionId = info.getInstitutionId();
            institutionName = institutionName == null ? "" : institutionName;
            institutionId = institutionId == null ? "" : institutionId;
            provinceName = info.getProvinceName();
            cityName = info.getCityName();
            districtName = info.getDistrictName();
        }

        // 当前年份下正式库中的数据
        List<CerDetaildataImportOfficeInfo> officeListByYear = map4Office.get(year);
        if (officeListByYear == null) {
            officeListByYear = new ArrayList<>();
        }
        // 从officeListByYear中,按照institutionName,查询出对应机构下的数据
        String finalInstitutionName = institutionName;
        List<CerDetaildataImportOfficeInfo> officeListByInstitutionName = officeListByYear
            .parallelStream()
            .filter(each1 -> each1.getInstitutionName() != null && each1
                .getInstitutionName()
                .equals(finalInstitutionName))
            .collect(Collectors.toList());
        // 初始数据正式库中符合条件的数据的个数
        int officeCount = officeListByInstitutionName.size();

        // 主键
        result.setId(UuidUtil.get32UUID());
        // 地区组合编码
        String[] split = key.split("\\|");
        // 省份
        result.setProvinceCode(split[0]);
        result.setProvinceName(provinceName);
        // 城市
        result.setCityCode(split[1]);
        result.setCityName(cityName);
        // 区县
        result.setRegionCode(split[2]);
        result.setRegionName(districtName);
        // 上报机构
        result.setInstitutionName(institutionName);
        result.setInstitutionId(institutionId);

        // 总量(初始数据正式库中符合条件的数据的个数)
        List<CerSysteminitImportOfficialInfo> tmp = map4InitOffice.get(year);
        // 二次过滤-通过机构名称过滤
        long count = tmp
            .stream()
            .filter(eachinfo -> eachinfo
                .getInstitutionName()
                .equals(finalInstitutionName))
            .count();

        result.setTotal(String.valueOf(count));

        // 临时库-应报数 (有错误的数据个数+无错误的数据个数)
        int lskYbs = errorCount + noErrorCount;
        result.setLskYbs(String.valueOf(lskYbs));
        // 临时库-上报进度 (应报数/应报数+初始数据正式库中的数据个数)
        String lskSbjd = getRate(lskYbs, lskYbs + officeCount);
        result.setLskSbjd(lskSbjd);
        // 临时库-合格
        result.setLskHg(String.valueOf(noErrorCount));
        // 临时库-不合格
        result.setLskBhg(String.valueOf(errorCount));
        // 临时库-合格率(合格/合格+不合格)
        String lskHgl = getRate(noErrorCount, noErrorCount + errorCount);
        result.setLskHgl(lskHgl);
        // 正式库-上报数
        result.setZskSbs(String.valueOf(officeCount));
        // 正式库-上报进度(正式库-上报数/应报数+正式库-上报数)
        String zskSbjd = getRate(officeCount, lskYbs + officeCount);
        result.setZskSbjd(zskSbjd);
        // 合计-应报数 (临时库-应报数+正式库-上报数)
        int hjYbs = lskYbs + officeCount;
        result.setHjYbs(String.valueOf(hjYbs));
        // 合计-上报进度(正式库-上报数/合计-应报数)
        result.setHjSbjd(getRate(officeCount, hjYbs));
        // 合计-合格
        result.setHjHg(String.valueOf(officeCount));
        // 合计-不合格
        result.setHjBhg(String.valueOf(errorCount));
        // 合计-合格率 (合格/合格+不合格)
        result.setHjHgl(getRate(officeCount, officeCount + errorCount));
        //初始数据类型
        result.setType(2);
        //deleted
        result.setDeleted(0);
        //插入时间
        result.setInsertDatetime(new Date(System.currentTimeMillis()));
        //更新时间
        result.setLastUpdateDatetime(new Date(System.currentTimeMillis()));
        //ext_flag => 地域数据
        result.setExtFlag(key);
        return result;
    }

    private List<CerReportProgress2> handleReginData(List<CerReportProgress2> list) {
        List<ZjcodeSysRegion> regions = new ArrayList<>();
        // 从缓存中获取数据
        String key = MConsts.URL_REGIONCODE_PREFIX + "LIST";
        String json = redisUtils.get(key);
        if (StringUtils.isNotEmpty(json)) {
            List<ZjcodeSysRegion> tmp = JSONObject.parseArray(json, ZjcodeSysRegion.class);
            regions.addAll(tmp);
        } else {
            regions.addAll(zjcodeSysRegionMapper.queryAllReginData());
            String tmp = JSONObject.toJSONString(regions);
            redisUtils.update(key, tmp);
        }

        list
            .parallelStream()
            .forEach(each -> {
                String cityId = each.getCityCode();
                String countyId = each.getRegionCode();
                regions
                    .parallelStream()
                    .forEach(item -> {
                        String code = item.getRegionCode();
                        each.setProvinceName("安徽省");
                        if (code.equals(cityId)) {
                            each.setCityName(item.getRegionName());
                        }
                        if (code.equals(countyId)) {
                            each.setRegionName(item.getRegionName());
                        }
                    });
            });
        return list;
    }

    /**
     * 重置list中的reginCode字段
     *
     * @param list
     * @return
     */
    private List<CerSysteminitImportInfo> resetRegionCode(List<CerSysteminitImportInfo> list) {
        list
            .parallelStream()
            .forEach(each -> {
                String provinceId = each.getProvinceId();
                String cityId = each.getCityId();
                String countyId = each.getDistrictId();
                String reginCode = provinceId + "|" + cityId + "|" + countyId;
                each.setRegionCode(reginCode);
            });
        return list;
    }

    private List<CerDetaildataImportInfo> handleData4Datail(List<CerDetaildataImportInfo> list) {
        list
            .parallelStream()
            .forEach(each -> {
                String provinceId = each.getProvinceId();
                String cityId = each.getCityId();
                String countyId = each.getDistrictId();
                String reginCode = provinceId + "|" + cityId + "|" + countyId;
                each.setRegionCode(reginCode);
            });
        return list;
    }

    // 获取比率
    private String getRate(int a, int b) {
        if (a != 0 || b != 0) {
            NumberFormat numberFormat = NumberFormat.getInstance();
            numberFormat.setMaximumFractionDigits(2);
            String result = numberFormat.format((float) a / (a + b) * 100);
            return result + "%";
        } else {
            return "0%";
        }
    }

    private List<CerSysteminitImportInfo> getListByErrorCode4Init(Map<Integer, List<CerSysteminitImportInfo>> map,
                                                                  int errorCode) {
        List<CerSysteminitImportInfo> list = map.get(errorCode);
        list = list == null ? new ArrayList<>() : list;
        return list;
    }

    private List<CerDetaildataImportInfo> getListByErrorCode4Detail(Map<Integer, List<CerDetaildataImportInfo>> map,
                                                                    int errorCode) {
        List<CerDetaildataImportInfo> list = map.get(errorCode);
        list = list == null ? new ArrayList<>() : list;
        return list;
    }

}
